# encoding:utf-8
import datetime
import time
from model.user import User
from tornado.web import HTTPError
from sqlalchemy.orm.exc import NoResultFound
from utils.signature import Signature
from tornado.gen import coroutine

class SignatureAuthMiddleware(object):
    @coroutine
    def process_request(self, request):
        # request是一个RequestHandler的实例
        # the middleware check that the signature is correct
        try:
            access_key = request.get_argument('access_key')
            signature = request.get_argument('signature')
            def _lambda(db):
                return db.query(User).filter_by(access_key=access_key).one()
            auth= yield request.asyncdb(_lambda)
            arguments = self.get_arguments(request)
            if not Signature(auth.secret_key, **arguments).check_signature(signature):
                raise HTTPError(401, "check signature error")
            request.auth = auth
        except NoResultFound:
            raise HTTPError(401, 'not find access key id')

    def get_arguments(self, request):
        exception_values = ('signature', 'secret_key',)
        arguments = {}
        for k in request.request.arguments:
            if k not in exception_values:
                arguments.update({k: request.get_argument(k)})
        return arguments


class TimeAuthMiddleware(object):
    def process_request(self, request):
        # request是一个RequestHandler的实例
        # the middleware check that the time is correct
        timestamp = request.get_argument('timestamp')
        if not self.check_timestamp(timestamp):
            raise HTTPError(401, 'check timestamp error')

    def check_timestamp(self, timestamp):
        timestamp = timestamp if isinstance(timestamp, str) else int(timestamp)
        request_time = time.mktime(time.localtime(timestamp))
        now_time = time.time()
        end_time = int(now_time -request_time)
        if end_time <= 180:
            return True
        else:
            return False


class PermissionCheckMiddleware(object):
    @coroutine
    def process_request(self, request):
        if hasattr(request, 'auth'):
            auth = request.auth
        else:
            access_key = request.get_argument('access_key')
            def _lambda(db):
                return db.query(User).filter_by(access_key=access_key).one()

            auth = yield request.asyncdb(_lambda)
        if not auth.is_superuser:
            raise HTTPError(401, 'requires system administrator privileges')


class CheckPoolMiddleware(object):
    def __init__(self, check_params_name='poolname'):
        self.check_params_name = check_params_name

    def process_request(self, request):
        # if hasattr(request, 'auth'):
        #     auth = request.auth
        # else:
        access_key = request.get_argument('access_key')

        def _lambda(db):
            return db.query(User).filter_by(access_key=access_key).one()
        auth = yield request.asyncdb(_lambda)
        pools = (pool.name for pool in auth.pools)
        poolname = request.get_argument(self.check_params_name)
        if poolname not in pools and not auth.is_superuser:
            raise HTTPError(401, 'You do not have permission to operate the storage pool')
